package com.google.code.mamule.mail;

import com.google.code.mamule.integration.Endpoint;
import com.google.code.mamule.integration.Message;
import com.google.code.mamule.order.Order;
import com.google.code.mamule.order.Order.State;
import com.google.code.mamule.user.ActiveUser;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.net.URI;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

/**
 * Created with IntelliJ IDEA. User: borck_000 ; Date: 12/9/13 ; Time: 4:25 PM
 */
@Component
@Path("/mail")
@Produces(MediaType.APPLICATION_JSON)
@Transactional
public class MailEndpoint {

  private final MailRepository mails;
  private final ActiveUser active;

  @Autowired
  public MailEndpoint(final MailRepository mails, ActiveUser active) {
    this.mails = mails;
    this.active = active;
  }

  @GET
  public Iterable<Mail> fetchAll() {
    return mails.findAllFrom(active.get());
  }

  @POST
  public Response create(@Context final UriInfo uri) {
    Mail created = new Mail();
    created.setOwner(active.get());
    created.setStatus(MailStatus.TRANSIENT);
    created.setText("Write me !");
    created = mails.save(created);
    final URI link = uri.getAbsolutePathBuilder().path(created.getId().toString()).build();
    return Response
        .created(link)
        .entity(Message.info(created.getId().toString()))
        .build();
  }

  @GET
  @Path("{mail-id}")
  public Mail fetchBy(@PathParam("mail-id") final Long id) {
    Mail found = mails.findByIdAndOwner(id, active.get());
    return Endpoint.failIfNull(found, "you have no mail with id %s", id);
  }

  @PUT
  @Path("/{mail-id}/print")
  public Response print(@PathParam("mail-id") Long id) {
    Mail found = mails.findByIdAndOwner(id, active.get());
    Endpoint.failIfNull(found, "you have no mail with id %s", id);
    
    Order o=mails.findOrder(found);
    
    if(o.getState()==State.CONFIRMED){
	    if (found.getStatus() == MailStatus.TRANSIENT || found.getStatus() == MailStatus.SUBMITTED) {
	      found.setStatus(MailStatus.PRINTED);
	      return Response.ok(Message.info("mail %s updated", id)).build();
	    } else {
	      return Response.notModified("Mail is not in Status transient").build();
	    }
    }else{
    	return Response.notModified("Order is not confirmed").build();
    }
  }

  
  @PUT
  @Path("/{mail-id}/send")
  public Response send(@PathParam("mail-id") Long id) {
    Mail found = mails.findByIdAndOwner(id, active.get());
    Endpoint.failIfNull(found, "you have no mail with id %s", id);
    
    Order o=mails.findOrder(found);
    
    if(o.getState()==State.CONFIRMED){
	    if (found.getStatus() == MailStatus.PRINTED) {
	      found.setStatus(MailStatus.SENT);
	      return Response.ok(Message.info("mail %s updated", id)).build();
	    } else {
	      return Response.notModified("Mail is not in Status printed").build();
	    }
    }else{
    	return Response.notModified("Order is not confirmed").build();
    }
  }

  @PUT
  @Path("/{mail-id}/deliver")
  public Response deliver(@PathParam("mail-id") Long id) {
    Mail found = mails.findByIdAndOwner(id, active.get());
    Endpoint.failIfNull(found, "you have no mail with id %s", id);
    
    
    Order o=mails.findOrder(found);
    
    if(o.getState()==State.CONFIRMED){    
	    if (found.getStatus() == MailStatus.SENT) {
	      found.setStatus(MailStatus.DELIVERED);
	      return Response.ok(Message.info("mail %s updated", id)).build();
	    } else {
	      return Response.notModified("Mail is not in Satus sent").build();
	    }
    }else{
    	return Response.notModified("Order is not confirmed").build();
    }
  }

  @PUT
  @Path("{mail-id}")
  @Consumes(MediaType.APPLICATION_JSON)
  public Response edit(@PathParam("mail-id") final Long id, final Mail content) {
    Mail found = mails.findByIdAndOwner(id, active.get());
    Endpoint.failIfNull(found, "you have no mail with id %s", id);
    found.setText(content.getText());
    found.setOptions(content.getOptions());
    found.setReceiver(content.getReceiver());
    return Response.ok(Message.info("mail %s updated", id)).build();
  }

  @PUT
  @Path("{mail-id}/text")
  @Consumes(MediaType.TEXT_PLAIN)
  public Response editText(@PathParam("mail-id") final Long id, final String text) {
    Mail found = mails.findByIdAndOwner(id, active.get());
    Endpoint.failIfNull(found, "you have no mail with id %s", id);
    found.setText(text);
    return Response.ok(Message.info("mail %s updated with new text", id)).build();
  }

  @PUT
  @Path("{mail-id}/text")
  @Consumes(MediaType.APPLICATION_JSON)
  public Response editText(@PathParam("mail-id") final Long id, final MailText text) {
    return editText(id, text.getText());
  }

  @DELETE
  @Path("{mail-id}")
  public Response remove(@PathParam("mail-id") final Long id) {
    Mail found = mails.findByIdAndOwner(id, active.get());
    Endpoint.failIfNull(found, "you have no mail with id %s", id);
    mails.delete(id);
    return Response.ok(Message.info("mail %s removed", id)).build();
  }
}
